// webpack 是node写出来的 node的写法
// 1、跨域处理
const path = require('path')
const Webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 用该插件 同时需要用uglifyjs-webpack-plugin才能压缩js 不然用optimize-css-assets-webpack-plugin插件就会不压缩js了
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const {
  CleanWebpackPlugin
} = require('clean-webpack-plugin') // 每次打包都删除 dist文件夹

const project = require('./src/utils/project.config');
const projectConfig = require(`./src/modules/${project.filename}/config`); //子项目配置
const env = process.env.NODE_ENV || 'development'; //获取当前执行环境
const paths = {
  root: path.resolve(process.cwd()), //脚本所在根目录
  srcPath: path.join(process.cwd(), 'src/modules', project.filename), //子项目开发目录
  distPath: projectConfig.output.path || path.join(process.cwd(), 'dist', project.filename) //子项目打包目录
};
console.log(process.env.NODE_ENV)
module.exports = {
  context: projectConfig.srcPath,
  mode: env, // 模式 默认两种 production(生产模式) development(开发模式)
  devtool: env === 'production' ? false : 'inline-source-map',
  entry: { // 多入口
    // index: './src/index.js'
    index: ['babel-polyfill', path.join(paths.srcPath, 'index.js')]
  },
  output: Object.assign({
    path: projectConfig.output.path || paths.distPath,
    filename: 'static/js/[name].[hash:7].js', //入口文件输出的文件名
    publicPath: ''
  }, env === 'production' ? {
    // chunkFilename: 'static/js/[name].js', //非入口文件输出的文件名
    publicPath: projectConfig.output.publicPath
  } : {}),
  optimization: { // 优化项
    minimizer: [
      new UglifyjsWebpackPlugin({ // js打包压缩
        cache: true, // 是否用这个缓存
        parallel: true, // 是否一起压缩多个
        sourceMap: true // es6 -> es5
      }),
      new OptimizeCssAssetsWebpackPlugin() // css打包压缩 
    ]
  },
  devServer: { // 开发服务的配置
    port: 3001, // 端口号
    progress: true, // 打包是出现进度条
    overlay: true, // 这个配置属性用来在编译出错的时候，在浏览器页面上显示错误，默认是false，可设置为true
    compress: true, // gzip压缩
    // autoOpenBrowser: true,
    host: 'localhost', // 设置的是服务器的主机号
    contentBase: paths.distPath, // 本地服务器所加载的页面所在的目录
    proxy: projectConfig.devServer.proxy //代理
  },
  performance: { // 性能提示
    hints: "warning", // 枚举
    maxAssetSize: 30000000, // 整数类型（以字节为单位）
    maxEntrypointSize: 50000000, // 整数类型（以字节为单位）
    assetFilter: function (assetFilename) {
      // 提供资源文件名的断言函数
      return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');

    }
  },
  plugins: [ // 数组 放着所有的webpack插件
    new CleanWebpackPlugin(), // 每次打包都将dist文件删除
    new HtmlWebpackPlugin({
      title: projectConfig.title || 'webpack',
      hash: env === 'production',
      filename: (env === 'production' && projectConfig.build.filename) || 'index.html',
      template: path.resolve(paths.srcPath, (env === 'production' && projectConfig.build.template) || 'index.html'),
      minify: { // html打包好压缩
        removeAttributeQuotes: true, // 删除html文件的双引号
        collapseWhitespace: false // 将html文件 打包成一行代码
      }
    }),
    new MiniCssExtractPlugin({ // css抽离
      filename: 'static/css/main.css' // 抽离出来的文件名
    }),
    // 全局引入第三方库
    new Webpack.ProvidePlugin({
      $: 'jquery'
    }),
    new VueLoaderPlugin("index.css"),
    new Webpack.BannerPlugin('make 2019 by LFZJ') // 版权所属
  ],
  module: { // 模块
    rules: [ // 规则
      {
        test: /\.js$/, // normal 普通的loader
        use: {
          loader: 'babel-loader',
          options: { //用babel-loader 需要把se6 -> es5
            presets: [ // 大插件的集合
              '@babel/preset-env'
            ],
            plugins: [ // 小插件 //解决es6的高级用法 如：class等等用法
              ["@babel/plugin-proposal-decorators", {
                "legacy": true
              }], // 用于解决class的装饰器 如 @log等
              ["@babel/plugin-proposal-class-properties", {
                "loose": true
              }], // 用于解决class类
              '@babel/plugin-transform-runtime' //同时要安装@babel/runtime(该插件生产环境要用) 解决相同代码共用的的问题及一些es6更高的语法
            ]
          }
        },
        include: path.resolve(__dirname, 'src'), // 要处理的那些文件下的文件
        exclude: /node_modules/ // 限制要处理的文件
      },
      {
        // 可处理css文件
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'vue-style-loader',
          'css-loader',
          'postcss-loader' // 给css3属性添加前缀 还要有一个postcss.config.js配置文件
        ]
      },
      {
        //可处理less文件 要安装(less,less-loader) 其它的类似如sass(node-sass,sass-loader),stylus(stylus,stylus-loader)
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'vue-style-loader',
          'css-loader', // @import  解析路径
          'postcss-loader', // 给css3属性添加前缀 还要有一个postcss.config.js配置文件
          'less-loader' // 把less -> css
        ]
      },
      {
        test: /\.html$/,
        use: 'html-withimg-loader'
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          extractCSS: true
        }
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        // 做一个限制 当我们的图片 小于多少k的时候 用base64 来转化
        // 否则用file-loader 产生真实的图片
        use: [{
            loader: 'url-loader',
            options: {
              limit: 10000, // 
              name: path.join('static', 'img/[name].[hash:7].[ext]')
              // publicPath: 'http://lfzj.com' // 单独给图片加域名
            }
          },
          {
            loader: 'image-webpack-loader',
            options: {
              name: path.join('static', 'img/[name].[hash:7].[ext]'),
              disable: true,
              bypassOnDebug: true
            }
          }
        ]
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          outputPath: './static/', // 打包的图片放到一个文件夹里
          name: path.join('media', '[name].[hash:7].[ext]')
        }
      },
    ]
  },
  resolve: {
    // 解析 第三方包
    modules: [path.resolve('node_modules')],
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue': 'vue/dist/vue.esm.js',
      '@': paths.srcPath,
      '@lang': path.resolve(paths.srcPath, './lang'), //TODO
      '@views': path.resolve(paths.srcPath, './views'),
      '@assets': path.resolve(paths.srcPath, './assets'),
      '@static': path.resolve(paths.srcPath, './static'),
      '@services': path.resolve(paths.srcPath, './services'), //TODO
      '@components': path.resolve(paths.srcPath, './components'),
      '@constant': path.resolve(paths.srcPath, './constant'), //TODO
    }
  }
}